//
// Created by huyi on 24-7-13.
//
#include "../AmdUtil.h"

#include <folly/Benchmark.h>
#include <folly/init/Init.h>

#include <gtest/gtest.h>

#include <stdexcept>
#include <vector>

using namespace tradev;

TEST(ParseDateTimeTest, ValidInput) {
  std::string      dateTimeStr = "20230712123456789";
  std::vector<int> expected    = {2023, 7, 12, 12, 34, 56, 789};
  std::vector<int> result      = parseDateTime(dateTimeStr);
  EXPECT_EQ(result, expected);
}

TEST(ParseDateTimeTest, InvalidLength) {
  std::string dateTimeStr = "2023071212345678"; // 少一位
  EXPECT_THROW(parseDateTime(dateTimeStr), std::invalid_argument);
}

TEST(ParseDateTimeTest, NonNumericInput) {
  std::string dateTimeStr = "2023ABCD123456789";
  EXPECT_THROW(parseDateTime(dateTimeStr), std::invalid_argument);
}

TEST(ParseDateTimeTest, ValidEdgeCase) {
  std::string      dateTimeStr = "00000101000000000";
  std::vector<int> expected    = {0, 1, 1, 0, 0, 0, 0};
  std::vector<int> result      = parseDateTime(dateTimeStr);
  EXPECT_EQ(result, expected);
}

TEST(ParseDateTimeTest, ValidLeapYear) {
  std::string      dateTimeStr = "20240229000000000"; // 闰年2月29日
  std::vector<int> expected    = {2024, 2, 29, 0, 0, 0, 0};
  std::vector<int> result      = parseDateTime(dateTimeStr);
  EXPECT_EQ(result, expected);
}

// 单元测试
TEST(ConvertPriceTest, BasicTest) {
  EXPECT_DOUBLE_EQ(convertPrice(900000), 0.9);
  EXPECT_DOUBLE_EQ(convertPrice(1000000), 1.0);
  EXPECT_DOUBLE_EQ(convertPrice(1234567890), 1234.56789);
}

TEST(ConvertPriceTest, BoundaryTest) {
  // 测试边界值
  EXPECT_DOUBLE_EQ(convertPrice(0), 0.0);
  EXPECT_DOUBLE_EQ(convertPrice(1), 0.000001);      // 因为 1/100000 向下取整为 0
  EXPECT_DOUBLE_EQ(convertPrice(99999), 0.099999);  // 99999/100000 向下取整为 0
  EXPECT_DOUBLE_EQ(convertPrice(999999), 0.999999); // 99999/100000 向下取整为 0
  EXPECT_DOUBLE_EQ(convertPrice(1000000), 1.0);     // 100000/100000 = 1
//  fmt::print("kDoubleMax = {}\n", kAmdPriceMuFactor * kDoubleMax);
//  EXPECT_DOUBLE_EQ(convertPrice(kAmdPriceMuFactor * kDoubleMax), kDoubleMax);
}

//TEST(ConvertPriceTest, LargeValuesTest) {
//  EXPECT_DOUBLE_EQ(convertPrice(1000000000000000), 10000000000.0);
//  EXPECT_DOUBLE_EQ(convertPrice(12345678901234567890ULL), folly::to<double>(folly::divFloor(12345678901234567890ULL, kAmdPriceMuFactor)));
//}
//
//// 单元测试
//TEST(ConvertVolumeTest, BasicTest) {
//  EXPECT_EQ(convertVolume(100000), 1);
//  EXPECT_EQ(convertVolume(200000), 2);
//  EXPECT_EQ(convertVolume(1234567890), 12345);
//}
//
//TEST(ConvertVolumeTest, BoundaryTest) {
//  // 测试边界值
//  EXPECT_EQ(convertVolume(0), 0);
//  EXPECT_EQ(convertVolume(1), 0);      // 因为 1/100000 向下取整为 0
//  EXPECT_EQ(convertVolume(99999), 0);  // 99999/100000 向下取整为 0
//  EXPECT_EQ(convertVolume(100000), 1); // 100000/100000 = 1
//  EXPECT_EQ(convertVolume(std::numeric_limits<uint64_t>::max()), folly::to<int64_t>(folly::divFloor(std::numeric_limits<uint64_t>::max(), kAmdVolumeMuFactor)));
//}
//
//TEST(ConvertVolumeTest, LargeValuesTest) {
//  EXPECT_EQ(convertVolume(1000000000000000), 10000000000);
//  EXPECT_EQ(convertVolume(12345678901234567890ULL), folly::to<int64_t>(folly::divFloor(12345678901234567890ULL, kAmdVolumeMuFactor)));
//}
//
//
//// 单元测试
//TEST(ConvertAmountTest, BasicTest) {
//  EXPECT_DOUBLE_EQ(convertAmount(100000), 1.0);
//  EXPECT_DOUBLE_EQ(convertAmount(200000), 2.0);
//  EXPECT_DOUBLE_EQ(convertAmount(1234567890), 12345.6789);
//}

//TEST(ConvertAmountTest, BoundaryTest) {
//  // 测试边界值
//  EXPECT_DOUBLE_EQ(convertAmount(0), 0.0);
//  EXPECT_DOUBLE_EQ(convertAmount(1), 0.0);      // 因为 1/100000 向下取整为 0
//  EXPECT_DOUBLE_EQ(convertAmount(99999), 0.0);  // 99999/100000 向下取整为 0
//  EXPECT_DOUBLE_EQ(convertAmount(100000), 1.0); // 100000/100000 = 1
//  EXPECT_DOUBLE_EQ(convertAmount(std::numeric_limits<uint64_t>::max()), folly::to<double>(folly::divFloor(std::numeric_limits<uint64_t>::max(), kAmdAmountMuFactor)));
//}
//
//TEST(ConvertAmountTest, LargeValuesTest) {
//  EXPECT_DOUBLE_EQ(convertAmount(1000000000000000), 10000000.0);
//  EXPECT_DOUBLE_EQ(convertAmount(12345678901234567890ULL), folly::to<double>(folly::divFloor(12345678901234567890ULL, kAmdAmountMuFactor)));
//}
//
//TEST(ConvertRateTest, BasicTest) {
//  EXPECT_DOUBLE_EQ(convertRate(100000), 1.0);
//  EXPECT_DOUBLE_EQ(convertRate(200000), 2.0);
//  EXPECT_DOUBLE_EQ(convertRate(1234567890), 12345.6789);
//}
//
//TEST(ConvertRateTest, BoundaryTest) {
//  // 测试边界值
//  EXPECT_DOUBLE_EQ(convertRate(0), 0.0);
//  EXPECT_DOUBLE_EQ(convertRate(1), 0.0);      // 因为 1/100000 向下取整为 0
//  EXPECT_DOUBLE_EQ(convertRate(99999), 0.0);  // 99999/100000 向下取整为 0
//  EXPECT_DOUBLE_EQ(convertRate(100000), 1.0); // 100000/100000 = 1
//  EXPECT_DOUBLE_EQ(convertRate(std::numeric_limits<uint64_t>::max()), folly::to<double>(folly::divFloor(std::numeric_limits<uint64_t>::max(), kAmdRateMuFactor)));
//}
//
//TEST(ConvertRateTest, LargeValuesTest) {
//  EXPECT_DOUBLE_EQ(convertRate(1000000000000000), 10000000.0);
//  EXPECT_DOUBLE_EQ(convertRate(12345678901234567890ULL), folly::to<double>(folly::divFloor(12345678901234567890ULL, kAmdRateMuFactor)));
//}

BENCHMARK(ParseDateTimeBench, iters) {
  std::string dateTimeStr = "20230712123456789";


  folly::StringPiece dateTime(dateTimeStr);
  while (iters--) {
    parseDateTime(dateTime);
  }
}

BENCHMARK_DRAW_LINE();

BENCHMARK(ConvertPriceBench, iters) {
  while (iters--) {
    folly::doNotOptimizeAway(convertPrice(12345678901234567890U));
  }
}

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);
  folly::Init init(&argc, &argv);
  gflags::ParseCommandLineFlags(&argc, &argv, true);

  auto ret = RUN_ALL_TESTS();
  if (ret == 0 && FLAGS_benchmark) {
    folly::runBenchmarks();
  }

  return ret;
}
